﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Text.RegularExpressions;

namespace BadassPhotoAlbum
{
    public partial class ControlForm : Form
    {
        Interface mainInterface; //this object does all the work
        private BackgroundWorker ThumbNailPopulator; //this is exactly what it sounds like
        private const int UNIQUE_ALBUM = -1; //so we don't have magic numbers floating around
        public delegate void AddListItem(Photo i); //Delegate function for preloading thumbnails
        private AddListItem AddListViewItemDelegate;
        ImageList SpecialImageList; //preloaded images for delegate function
        private bool FirstSelectAlbumAsyncCall = true; //delegate function call flag

        public ControlForm()
        {
            InitializeComponent();
            SpecialImageList = new ImageList();
            SpecialImageList.ColorDepth = ColorDepth.Depth16Bit;
            SpecialImageList.ImageSize = new Size(60, 60);

            mainInterface = new Interface();
            //Thread.Sleep(1); //forces starting of async processes

            //init the album list
            SetAlbumList();            
            InitAlbumList();

            //init all the album list events
            AlbumList.CellClick += new DataGridViewCellEventHandler(AlbumList_CellClick);
            AlbumList.KeyDown += new KeyEventHandler(AlbumList_KeyDown);
            AlbumList.AllowDrop = true;
            AlbumList.DragOver += new DragEventHandler(AlbumList_DragOver);
            AlbumList.DragDrop += new DragEventHandler(AlbumList_DragDrop);
            AlbumList.CellEnter += new DataGridViewCellEventHandler(AlbumList_CellEnter);

            //init all the thumbnail list events
            ThumbnailView.KeyDown += new KeyEventHandler(ThumbnailView_KeyDown);
            ThumbnailView.DoubleClick += new EventHandler(ThumbnailView_DoubleClick);
            ThumbnailView.AllowDrop = true;
            ThumbnailView.DragDrop += new DragEventHandler(ThumbnailView_DragDrop);
            ThumbnailView.DragOver += new DragEventHandler(ThumbnailView_DragOver);
            ThumbnailView.Click += new EventHandler(ThumbnailView_Click);
            ThumbnailView.ItemDrag += new ItemDragEventHandler(ThumbnailView_ItemDrag);
            ThumbnailView.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(ThumbnailView_ItemSelectionChanged);


            ThumbNailToolTip.SetToolTip(ThumbnailView, ""); //setup thumbnail tooltips and warnings
            AlbumListToolTip.SetToolTip(AlbumList, "");

            AlbumList.ContextMenuStrip = AlbumContextMenu;
            ThumbnailView.ContextMenuStrip = PhotoContextMenu;

            //init the thumnail generator threads
            AlbumContextMenu.Opening += new CancelEventHandler(AlbumContextMenu_Opening);
            PhotoContextMenu.Opening += new CancelEventHandler(PhotoContextMenu_Opening);
            ThumbNailPopulator = new BackgroundWorker();
            ThumbNailPopulator.DoWork += new DoWorkEventHandler(ThumbNailPopulator_DoWork);
            ThumbNailPopulator.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ThumbNailPopulator_RunWorkerCompleted);

            this.SelectAlbum(UNIQUE_ALBUM,true);
        }

        /// <summary>
        /// This function selects the proper photo for selection.
        /// The GUI will have the proper photo selected.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ThumbnailView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            this.SelectPhoto();
        }

        /// <summary>
        /// This function selects the proper album.
        /// The GUI will have the proper album selected and displayed.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void AlbumList_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (mainInterface.CurrentlySelectedAlbum == -2) //magic number for un-init
                return;
            int newIndex = e.RowIndex;
            string albumName = AlbumList.Rows[newIndex].Cells[0].Value.ToString();
            Album album = mainInterface.GetAlbumByName(albumName);

            ClearPhotoText();

            if (album == null)
            {
                SelectAlbum(UNIQUE_ALBUM);
            }
            else
                SelectAlbum(album.getAlbumID());
        }

        //DRAG AND DROP (a Mike Flood solo) //Adam Reaves - Mike thinks he's soooo cool. (modified var names)
        ///<summary>
        ///This function is used to begin the drag and drop event, when the user mouses-down on the image
        ///created by Michael Flood, Nov 7, 2011
        ///</summary>
        void ThumbnailView_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                List<Photo> selPhotoList = new List<Photo>();

                Album selectedAlbum;
                if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                    selectedAlbum = mainInterface.GetUniquePhotoAlbum();
                else
                    selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);
                
                //get the list of photos selected by the user
                for (int i = 0; i < ThumbnailView.SelectedItems.Count; i++)
                {
                    int pID = selectedAlbum.getPhotoList()[ThumbnailView.SelectedIndices[i]].GetPhotoID();
                    selPhotoList.Add(selectedAlbum.getPhotobyID(pID));
                }
                //copy the selected item to the list
                ThumbnailView.DoDragDrop(selPhotoList, DragDropEffects.Copy);
            }
            return;
        }

        /// <summary>
        /// This function selects the proper album for the photos to drop.
        /// The GUI will have the proper album selected and displayed.
        /// Written By: Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void AlbumList_DragDrop(object sender, DragEventArgs e)
        {
            this.AddPhotosByDrop(e);
        }

        /// <summary>
        /// This function is called when the mouse goes over the album list while in a drag over even
        /// It changes the currently selected album and the cursor depending on what kind of item
        /// is being dragged over
        /// Written By: Adam Reaves
        /// </summary>
        void AlbumList_DragOver(object sender, DragEventArgs e)
        {
            DataGridView.HitTestInfo hitTest;

            if (e.Data.GetDataPresent(DataFormats.FileDrop)) //if it's frome xplorere
            {
                e.Effect = DragDropEffects.Copy;
            }
            else if(e.Data.GetDataPresent(typeof(List<Photo>))) //if it's from the program
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
                return;

            //turn screen coors into relative coors
            Point lPoint = AlbumList.PointToClient(new Point(e.X, e.Y));
            //dereference the x,y to a potential cell
            hitTest = AlbumList.HitTest(lPoint.X, lPoint.Y);
     
            //see what the mouse is over
            if (hitTest.Type == DataGridViewHitTestType.Cell) //if it's a cell
            {
                if (AlbumList.Rows[hitTest.RowIndex].Cells[0].Selected == true) //if it's already selected
                    return; //return to save CPU

                int dragAlbumID = mainInterface.GetAlbumByName(AlbumList.Rows[hitTest.RowIndex].Cells[0].Value.ToString()).getAlbumID();
                AlbumList.Rows[hitTest.RowIndex].Cells[0].Selected = true; //select the cell
                this.SelectAlbum(dragAlbumID); //select the album
            }
        }

        /// <summary>
        /// This function is called when the mouse goes over the photo list while in a drag over even
        /// It changed the mouse for further checks depending on what kind of item is in the drag event
        /// Written By: Adam Reaves
        /// </summary>
        void ThumbnailView_DragOver(object sender, DragEventArgs e)
        {
            if (mainInterface.CurrentlySelectedAlbum == -1)
                return;
            if(e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else if(e.Data.GetDataPresent(typeof(List<Photo>)))
                e.Effect = DragDropEffects.Copy;
            else
                return;
            return;
  
        }

        /// <summary>
        /// This function is called when the mouse is released in a drag event over the thumbnails
        /// It gets the items and passes it elsewhere
        /// Written by: Adam Reaves
        /// </summary>
        void ThumbnailView_DragDrop(object sender, DragEventArgs e)
        {
            AddPhotosByDrop(e);
        }

        /// <summary>
        /// This function creates and displays a progress bar.
        /// The GUI will display and increment a progress bar.
        /// Written By: Adam Reaves
        /// </summary>
        /// <param name="e"></param>
        private void AddPhotosByDrop(DragEventArgs e)
        {
            string[] filePaths;
            Point adjP = ThumbnailView.PointToClient(new Point(e.X, e.Y));
            int addIndex =this.GetThumbnailViewPhotoIndexAtPoint(adjP); //get the index the mouse is over

            if (e.Effect == DragDropEffects.Copy) //indicating a drop from 
            {
                //prevent thread invoke issues by dissasocating the large image list
                ThumbnailView.LargeImageList = null;

                //generate the progress bar
                ProgressBar addPhotoProgBar = new ProgressBar();
                addPhotoProgBar.Visible = true;
                addPhotoProgBar.Location = new System.Drawing.Point(50, 50);
                addPhotoProgBar.Name = "progress bar";
                addPhotoProgBar.Width = 300;
                addPhotoProgBar.Height = 30;
                addPhotoProgBar.Minimum = 0;

                addPhotoProgBar.Value = 1;
                addPhotoProgBar.Step = 1;
                Controls.Add(addPhotoProgBar);
                addPhotoProgBar.Parent = ThumbnailView;
                addPhotoProgBar.BringToFront();


                if(e.Data.GetDataPresent(DataFormats.FileDrop)) //if it's from explorer
                {
                    filePaths = (string[])e.Data.GetData(DataFormats.FileDrop);
                    addPhotoProgBar.Maximum = filePaths.Count() + 1;
    
                    foreach (string s in filePaths) //parse the file list
                    {
                        if (addIndex != -1) //if there is an index add at index
                            mainInterface.DragFileToAlbum(s, mainInterface.CurrentlySelectedAlbum,addIndex);
                        else //if not, add at end
                            mainInterface.DragFileToAlbum(s, mainInterface.CurrentlySelectedAlbum);
                        addPhotoProgBar.Value = addPhotoProgBar.Value + 1;
                    }
                }
                else //if it's a list of photos
                {
                    List<Photo> photoList = (List<Photo>)e.Data.GetData(typeof(List<Photo>));
                    addPhotoProgBar.Maximum = photoList.Count() + 1;

                    foreach (Photo p in photoList) //enum through photos
                    {
                        try
                        {
                            if (addIndex != -1) //if theres an index to add to add at index
                                mainInterface.AddPhotoToAlbum(mainInterface.CurrentlySelectedAlbum, p, addIndex);
                            else //add at end
                                mainInterface.AddPhotoToAlbum(mainInterface.CurrentlySelectedAlbum, p);
                            addPhotoProgBar.Value = addPhotoProgBar.Value + 1;
                        }
                        catch
                        {
                            SelectAlbum(mainInterface.CurrentlySelectedAlbum, true);
                            //end the progress bar
                            addPhotoProgBar.Value = 0;
                            addPhotoProgBar.Visible = false;
                            addPhotoProgBar.Dispose();
                        }
                    }
                }
                //for consistancy, select the album
                SelectAlbum(mainInterface.CurrentlySelectedAlbum,true);
                //end the progress bar
                addPhotoProgBar.Value = 0;
                addPhotoProgBar.Visible = false;
                addPhotoProgBar.Dispose();
            }
            
        }

        /// <summary>
        /// This function attempts to get an index from a point in the thumbnail list
        /// Has to be in try catches because it's an access violation if there is no item found
        /// Written by: Adam Reaves
        /// </summary>
        int GetThumbnailViewPhotoIndexAtPoint(Point p)
        {
            //try a bunch of methods to get an index
            try //right is the hihest prio
            {
                return ThumbnailView.FindNearestItem(SearchDirectionHint.Right, p).Index - 1;
            }
            catch
            {
                try //then at the index
                {
                    return ThumbnailView.GetItemAt(p.X, p.Y).Index;
                }
                catch
                {
                    try //then at the left
                    {
                        return ThumbnailView.FindNearestItem(SearchDirectionHint.Left, p).Index + 1;
                    }
                    catch //if it's none of the above
                    {
                        return -1;
                    }
                }
            }
        }
        /// <summary>
        /// is called when the thumnail thread either gets the big photo list from the interface
        /// or finishes generating it's own image list
        /// Written by: Adam Reaves
        /// </summary>
        void ThumbNailPopulator_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Album theAlbum;
            ImageList iList = (ImageList)e.Result;
            int albumID = mainInterface.CurrentlySelectedAlbum;

            if (albumID == -1)//get the album from dereference
                theAlbum = mainInterface.GetUniquePhotoAlbum();
            else
                theAlbum = mainInterface.GetAlbumById(albumID);

            ThumbnailView.Items.Clear();

            ThumbnailView.LargeImageList = iList;

            //each photo now has an image associated with it
            foreach (Photo p in theAlbum.getPhotoList())
            {
                ListViewItem item = new ListViewItem(p.PhotoName, 0);// create an item that is a row in listview
                item.ImageIndex = iList.Images.IndexOfKey(p.GetPhotoID().ToString());
                ThumbnailView.Items.Add(item);
            }
            ThumbnailView.Show();
        }
        /// <summary>
        /// This function is the invoke the make the generation of thumbnails appear on screen
        /// C# prevents threads from accessing display object from threads other than it was created in
        /// This type of function allows the main thread to be preempted and modify it itself
        /// Written by: Adam Reaves
        /// </summary>
        public void ThumbnailPopulateInvoke(Photo p)
        {
            ThumbnailView.LargeImageList = SpecialImageList; //if this was called, we're individually generating

            //if it's already been genrated; return
            if(SpecialImageList.Images.ContainsKey(p.GetPhotoID().ToString()))
                return; //save CPU
            
            //add the thumb to the image list from the main thread
            SpecialImageList.Images.Add(p.GetPhotoID().ToString(), Image.FromStream(p.GetFileDescriptor()));

            ListViewItem item = new ListViewItem(p.PhotoName,0);// create an item that is a row in listview
            item.ImageIndex = SpecialImageList.Images.IndexOfKey(p.GetPhotoID().ToString());

            ThumbnailView.Items.Add(item);
            //ThumbnailView.Show();
        }

        /// <summary>
        ///Called whenever an album is selected. It attempts to start generating thumbnails while the interface
        ///is generating the big thumbnail list to prevent the user from having to wait as long
        ///Written by: Adam Reaves
        /// </summary>
        void ThumbNailPopulator_DoWork(object sender, DoWorkEventArgs e)
        {
            ImageList listAquire = mainInterface.GetThumbnailImageList(); //try and get the main list
            int curIndex = 0;
            Album curAlbum;
            Photo curPhoto;
            //dereference the album
            if(mainInterface.CurrentlySelectedAlbum != UNIQUE_ALBUM)
                curAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);
            else
                curAlbum = mainInterface.GetUniquePhotoAlbum();

            if (curAlbum == null)
                return; //some odd error
            //SpecialImageList.Images.Clear();

            //drop this priority to low
            Thread.CurrentThread.Priority = ThreadPriority.Lowest;
            //ThumbnailView.LargeImageList = SpecialImageList; //default to normal list
            while ((listAquire = mainInterface.GetThumbnailImageList() ) == null) //try and get the main list again
            {
                if (FirstSelectAlbumAsyncCall) //if it's the first call
                {
                    Thread.Sleep(200); //(because this is called by the main thread it will slow it dow)
                    //this call attempts to let the main thread finish drawing before any invokes are called
                    FirstSelectAlbumAsyncCall = false;
                }
                
                if(curIndex < curAlbum.getPhotoList().Count) //while not all the thumbnails are generated
                {
                    //InvokeMutex.WaitOne();
                    curPhoto = curAlbum.getPhotoList()[curIndex];
                    AddListViewItemDelegate = new AddListItem(ThumbnailPopulateInvoke);
                    try
                    {
                        ThumbnailView.Invoke(AddListViewItemDelegate, curPhoto); //invoke a thumbnails creation
                    }
                    catch
                    {
                        continue;
                    }
                }
                else
                {
                    e.Result = SpecialImageList; //if it generates them before the background thread
                    return;
                }
                curIndex++;
            }

            e.Result = listAquire; //aquired big list first
        }

        /// <summary>
        /// called when a cell is clicked by the mouse
        /// Changed the current album and sets all the higlight to the furthest left cell
        /// Written by: Adam Reaves
        /// </summary>
        void AlbumList_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            string albumName;
            try
            {
                //get the album name
                albumName = AlbumList.Rows[e.RowIndex].Cells[0].Value.ToString();
            }
            catch
            {
                return; //not valid
            }

            //get the albumID from name
            int albumID = mainInterface.GetPhotoIDByName(albumName);

            if (e.ColumnIndex == 1) //if this is a button column
            {
                if (albumID == UNIQUE_ALBUM)
                {
                    AlbumList.Rows[0].Cells[0].Selected = true;
                    return; //either doesn't exist or is all albums
                }
                AlbumList.Rows[e.RowIndex].Cells[0].Selected = true;

                this.AddPhotoByPrompt(albumID);
            }
            else //it's an albumname column
            {
               this.SelectAlbum(albumID);               
            }
        }

        /// <summary>
        /// This function adds an album by wizard.
        /// The GUI will display the Album Wizard.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void AddAlbumByWizard()
        {
            AlbumWizard wizard = new AlbumWizard(mainInterface);
            wizard.ShowDialog();

            if (!wizard.Valid)
                return;

            this.AddAlbumByName(wizard.AlbumName.Trim(), wizard.AlbumDescription.Trim(), true);
        }

        /// <summary>
        /// Adds an album to the albumlist and the interface by passing it's name
        /// The isnew is here for initial generation. It's NOT new on initial album generation
        /// Written by: Adam Reaves
        /// </summary>
        private void AddAlbumByName(string name, string desc, bool isNew)
        {
            if (name.Trim() == "")
                return; //this is blank and should not be added

            int nextEntry = AlbumList.Rows.Count;
            AlbumList.Rows.Add();
            AlbumList.Rows[nextEntry].Cells[0].Value = name;
            AlbumList.Rows[nextEntry].Cells[1].Value = "+";
            AlbumList.Rows[nextEntry].Resizable = DataGridViewTriState.False;

            if (isNew)
                mainInterface.AddAlbum(name, desc);
        }

        /// <summary>
        /// This function creates and displays a progress bar when adding photos.
        /// The GUI will display and increment a progress bar once photos are added.
        /// Written By: Adam Reaves & Mike Flood
        /// </summary>
        /// <param name="albumID"></param>
        private void AddPhotoByPrompt(int albumID)
        {
            //generate a prompt
            OpenFileDialog openFile = new OpenFileDialog();

            //filter it on only files we want
            openFile.Filter = "Pictures (*.jpg, *.jpeg, *bmp, *.png)| *.jpg; *.jpeg; *.bmp; *.png";
            openFile.Multiselect = true;
            openFile.ShowDialog();

            if (openFile.SafeFileNames.Count() == 0)
                return;

            ThumbnailView.LargeImageList = null;
            int fullFileNameIndex = 0;

            //generate a progress bar
            ProgressBar addPhotoProgBar = new ProgressBar();
            addPhotoProgBar.Visible = true;
            addPhotoProgBar.Location = new System.Drawing.Point(50, 50);
            addPhotoProgBar.Name = "progress bar";
            addPhotoProgBar.Width = 300;
            addPhotoProgBar.Height = 30;
            addPhotoProgBar.Minimum = 0;
            addPhotoProgBar.Maximum = openFile.SafeFileNames.Count() + 1;
            addPhotoProgBar.Value = 1;
            addPhotoProgBar.Step = 1;
            Controls.Add(addPhotoProgBar);
            addPhotoProgBar.Parent = ThumbnailView;
            addPhotoProgBar.BringToFront();
            //for every file, create a new photo
            foreach (string fName in openFile.SafeFileNames)
            {
                mainInterface.AddPhotoToAlbum(albumID, fName, "", openFile.FileNames[fullFileNameIndex]);
                fullFileNameIndex++;
                addPhotoProgBar.Value = addPhotoProgBar.Value + 1;
            }
            //delete the progress bar
            addPhotoProgBar.Value = 0;
            addPhotoProgBar.Visible = false;
            addPhotoProgBar.Dispose();
            //select the ablum we just changed and force an upodate
            SelectAlbum(albumID,true);
        }

        /// <summary>
        /// This function initiates the album list.
        /// The GUI will display and set the album list.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        private void InitAlbumList()
        {
            List<Album> albumList = mainInterface.GetAlbumList();

            foreach (Album album in albumList)
            {
                AddAlbumByName(album.AlbumName, album.AlbumDescription, false);
            }
        }

        /// <summary>
        /// This function attempts to get an index from a point in the thumbnail list
        /// Has to be in try catches because it's an access violation if there is no item found
        /// Written by: Adam Reaves
        /// </summary>
        private void PopulateThumbnailsView(int albumID)
        {

            if (ThumbNailPopulator.IsBusy) //check to see if it's already working
                return;

            ImageList iList = mainInterface.GetThumbnailImageList();


            if (iList != null)
            {
                Album theAlbum;

                if (albumID == UNIQUE_ALBUM)
                    theAlbum = mainInterface.GetUniquePhotoAlbum();
                else
                    theAlbum = mainInterface.GetAlbumById(albumID);

                ThumbnailView.Items.Clear();

                ThumbnailView.LargeImageList = iList;

                foreach (Photo p in theAlbum.getPhotoList())
                {
                    ListViewItem item = new ListViewItem(p.PhotoName, 0);// create an item that is a row in listview
                    item.ImageIndex = iList.Images.IndexOfKey(p.GetPhotoID().ToString());
                    ThumbnailView.Items.Add(item);
                }
                ThumbnailView.Show();
            }
            else
            {
                ThumbNailPopulator.RunWorkerAsync();
            }
        }
        
        /// <summary>
        /// This function selects and displays a photo for various tasks.
        /// The GUI will select photo thumbnail for various tasks.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        void SelectPhoto()
        {
            // Select album to add photo too
            Album selectedAlbum;
            int albumID = mainInterface.CurrentlySelectedAlbum;

            // If no photos are selected, Disable tool strip menu items.
            if (ThumbnailView.SelectedItems.Count == 0)
            {
                DisableToolStripMenuSpecials(albumID);
                return;
            }

            // Select proper album
            if (albumID == UNIQUE_ALBUM)
                selectedAlbum = mainInterface.GetUniquePhotoAlbum();
            else
                selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);


            Photo pID = selectedAlbum.getPhotoList()[ThumbnailView.SelectedIndices[0]];

            // Select photo and display information
            photoNameLabel.Text = pID.PhotoName;
            SetPhotoDescrip(pID.PhotoDescription);
            EnableToolStripMenuSpecials(albumID);
        }

        /// <summary>
        /// This function selects and prepares a photo for editing.
        /// The GUI will select photo thumbnail for editing.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void EditPhoto()
        {
            //if nothing is selected then an error message is displayed
            if (ThumbnailView.SelectedItems.Count == 0)
            {
                ThumbNailToolTip.Show("Please Select A Photo For Editing", ThumbnailView, 0, 0, 3000);
                return;
            }
            //the user cannot select multiple photos to edit at one time
            if (ThumbnailView.SelectedItems.Count > 1)
            {
                ThumbNailToolTip.Show("Please Select A Single Photo For Editing", ThumbnailView, 0, 0, 3000);
                ThumbnailView.SelectedItems.Clear();
                return;
            }

            // Select proper album
            Album curAlbum;

            curAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // Select photo for editing
            Photo tempP = curAlbum.getPhotoList()[ThumbnailView.SelectedIndices[0]];
            
            // Open Photo Wizard for Editing
            PhotoWizard wizard = new PhotoWizard(tempP.PhotoName, tempP.PhotoDescription);
            wizard.ShowDialog();

            // If Photo Wizard is not Valid, Return.
            if (!wizard.Valid)
                return;

            mainInterface.ModifyPhoto(tempP.GetPhotoID(), wizard.PhotoName, wizard.PhotoDescription);

            // Edit photo and reselect it
            int capturedIndex = ThumbnailView.SelectedIndices[0];
            SelectAlbum(curAlbum.getAlbumID(), true); //update the thumnails
            ThumbnailView.Items[capturedIndex].Selected = true;
            SelectPhoto();
        }

        /// <summary>
        /// This function selects and prepares a photo for viewing.
        /// The GUI will select photo thumbnail for viewing.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void ViewPhoto()
        {
            // If no photos are selected
            if (ThumbnailView.SelectedItems.Count == 0)
            {
                ThumbNailToolTip.Show("Please Select A Photo For Viewing", ThumbnailView, 0, 0, 3000);
                return;
            }
            //the user cannot select multiple photos to edit at one time
            if (ThumbnailView.SelectedItems.Count > 1)
            {
                ThumbNailToolTip.Show("Please Select A Single Photo For Viewing", ThumbnailView, 0, 0, 3000);
                ThumbnailView.SelectedItems.Clear();
                return;
            }

            // Select proper album
            Album selectedAlbum;

            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                selectedAlbum = mainInterface.GetUniquePhotoAlbum();
            else
                selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // Select photo for viewing
            Photo pID = selectedAlbum.getPhotoList()[ThumbnailView.SelectedIndices[0]];
            SinglePhotoViewForm photoViewForm = new SinglePhotoViewForm(pID);
            photoViewForm.Show();           // display photo view form
            photoViewForm.BringToFront();
        }
        
        /// <summary>
        /// This function checks for multiple photos to be deleted.
        /// The database will be updated to reflect changes.
        /// Written By: Steven Gonzalez
        /// </summary>
        private void DeletePhoto()
        {
            // If All Photos Album is selected, cannot delete photo
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM) //check to make sure all albums isn't selected
            {
                AlbumListToolTip.Show("Unable To Delete From 'All Photos' Album", ThumbnailView, 0, 0, 3000);
                return;
            }

            List<int> photoIdstoDelete = new List<int>();
            Album selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // Add photos to a list to be deleted
            for (int i = 0; i < ThumbnailView.SelectedIndices.Count; i++)
            {
                int pID = selectedAlbum.getPhotoList()[ThumbnailView.SelectedIndices[i]].GetPhotoID();
                photoIdstoDelete.Add(pID);
            }

            // If more then one photo is selected to be deleted
            if (photoIdstoDelete.Count > 1)
            {
                DialogResult confirmMulti = MessageBox.Show("Multiple Photos Selected: (" + photoIdstoDelete.Count
                    + ") Delete These Photos?", "Delete Multiple Photos",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);

                // If yes, delete all photos
                if (confirmMulti == DialogResult.Yes)
                {
                    foreach (int loc in photoIdstoDelete)
                    {
                        mainInterface.DeletePhoto(selectedAlbum.getAlbumID(), loc);
                    }
                }
                // If cancel, return to the App
                else if(confirmMulti == DialogResult.Cancel)
                {
                    return;
                }
                // Else, ask to delete individual photo
                else
                {
                    DeleteSinglePhoto(photoIdstoDelete, selectedAlbum);
                }
            }
            // Else, ask to delete individual photo
            else
            {
                DeleteSinglePhoto(photoIdstoDelete, selectedAlbum);
            }
            // Reselect the album to repopulate the view
            this.SelectAlbum(selectedAlbum.getAlbumID()); 
        }

        /// <summary>
        /// This function deletes individual photos from the thumbnail view.
        /// The database will be updated to reflect changes.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="photoIdstoDelete"></param>
        /// <param name="selectedAlbum"></param>
        private void DeleteSinglePhoto(List<int> photoIdstoDelete, Album selectedAlbum)
        {
            // For each photo, ask to delete individual photo
            foreach (int loc in photoIdstoDelete)
            {
                DialogResult confirm = MessageBox.Show("Delete The Individual Photo?: "
                    + mainInterface.GetPhotoByID(loc).PhotoName, "Delete Individual Photo",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                // If yes, delete individual photo
                if (confirm == DialogResult.Yes)
                {
                    mainInterface.DeletePhoto(selectedAlbum.getAlbumID(), loc);
                }
                // If cancel, return to the App
                else if (confirm == DialogResult.Cancel)
                {
                    return;
                }
            }
        }

        /// <summary>
        /// This function selects the proper album to display.
        /// The GUI will update selected Album and update form.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="albumID"></param>
        void SelectAlbum(int albumID)
        {
            //set the album name and count
            Album curAlbum;

            if (albumID == UNIQUE_ALBUM)
            {
                curAlbum = mainInterface.GetUniquePhotoAlbum();
                //AlbumList.Rows[0].Cells[0].Selected = true;
            }
            else
                curAlbum = mainInterface.GetAlbumById(albumID);

            // Update Album Description on GUI
            AlbumGroupBox.Text = curAlbum.AlbumName + " - " + curAlbum.getPhotoList().Count + " Photos";
            albumNameLabel.Text = curAlbum.AlbumName;
            albumCountLabel.Text = curAlbum.getPhotoList().Count.ToString() + " Photos";
            SetAlbumDescrip(curAlbum.AlbumDescription);

            // Disable Tool Strip Menu Items based on album
            DisableToolStripMenuSpecials(albumID);

            if (ThumbnailView.Items.Count == curAlbum.getPhotoList().Count && albumID == mainInterface.CurrentlySelectedAlbum) //if it's already fully populated, don't populate again
                return;

            this.PopulateThumbnailsView(albumID);
            mainInterface.CurrentlySelectedAlbum = albumID; //keep track of status
        }

        /// <summary>
        /// This function selects the proper album to display.
        /// The GUI will update selected Album and update form.
        /// Boolean forces an update on selected album.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="albumID"></param>
        /// <param name="forceUpdate"></param>
        public void SelectAlbum(int albumID, Boolean forceUpdate)
        {
            SelectAlbum(albumID);
            this.PopulateThumbnailsView(albumID);
        }

        /// <summary>
        /// This function selects and deletes the proper album.
        /// The GUI will delete the Album and update Album List.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void DeleteAlbum()
        {
            // If All Photos Album is selected, cannot delete
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM) //check to make sure all albums isn't selected
            {
                AlbumListToolTip.Show("Unable To Delete 'All Photos' Album", ThumbnailView,0, 0, 3000);
                return;
            }

            // If No Albums are selected, cannot delete
            if (AlbumList.SelectedCells.Count == 0)
            {
                AlbumListToolTip.Show("No Albums Selected To Delete", ThumbnailView, 0, 0, 3000);
                return;
            }
            Album selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            //make sure the user didn't make a mistake
            DialogResult confirm = MessageBox.Show("Are you sure you want to delete the selected album: "
                + selectedAlbum.AlbumName, "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (confirm == DialogResult.No)
                return;

            //delete the row from the display
            int deleteIndex = AlbumList.SelectedCells[0].RowIndex;
            AlbumList.Rows.RemoveAt(deleteIndex);

            //delete selected album
            mainInterface.DeleteAlbum(selectedAlbum.getAlbumID());

            this.SelectAlbum(UNIQUE_ALBUM); //select all albums (to keep a good state)
            //stupid reentrant fix for deletion
            AlbumList.Rows[0].Cells[0].Selected = true;
        }

        /// <summary>
        /// This function selects and edit the proper album.
        /// The GUI will edit the Album and update Album List.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void EditAlbum()
        {
            // If All Photos Album is selected, cannot edit
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM) //check to make sure all albums isn't selected
            {
                AlbumListToolTip.Show("Unable To Edit 'All Photos' Album", ThumbnailView, 0, 0, 3000);
                return;
            }

            // Select proper album
            Album selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // Open Album Wizard to edit album
            AlbumWizard wizard = new AlbumWizard(mainInterface, "Edit Album",
                selectedAlbum.AlbumName, selectedAlbum.AlbumDescription);
            wizard.ShowDialog();

            // If Album Wizard is not valid, Return
            if (!wizard.Valid)
                return;

            //modify it in the interface
            mainInterface.ModifyAlbum(selectedAlbum.getAlbumID(), wizard.AlbumName, wizard.AlbumDescription);

            //modify the albumlist
            AlbumList.SelectedCells[0].Value = selectedAlbum.AlbumName;
            this.SelectAlbum(selectedAlbum.getAlbumID());
        }

        /// <summary>
        /// This function selects a Photo and Starts the Slide Show.
        /// The GUI will open a form to display Slide Show
        /// Written By: Adam Reaves & Steven Gonzalez 
        /// </summary>
        private void StartSlideShow()
        {
            // Select proper album
            Album selectedAlbum;

            // If All Photos Album is selected
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                selectedAlbum = mainInterface.GetUniquePhotoAlbum();
            else
                selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // If no photos exist in Album
            if (selectedAlbum.getPhotoList().Count == 0)
                return;

            // Create SlideShowForm and being Slide Show
            SlideShowForm slideShow = new SlideShowForm(selectedAlbum);
            slideShow.Show();
        }

        /// <summary>
        /// This function selects a Photo and Starts the Slide Show.
        /// The GUI will open a form to display Slide Show at a selected index.
        /// Written By: Adam Reaves & Steven Gonzalez  
        /// </summary>
        /// <param name="index"></param>
        private void StartSlideShowAtPicture(int index)
        {
            // Select proper album
            Album selectedAlbum;

            // If All Photos Album is selected
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                selectedAlbum = mainInterface.GetUniquePhotoAlbum();
            else
                selectedAlbum = mainInterface.GetAlbumById(mainInterface.CurrentlySelectedAlbum);

            // If no photos exist in Album
            if (selectedAlbum.getPhotoList().Count == 0)
                return;

            // Create SlideShowForm and being Slide Show at selected photo
            SlideShowForm slideshow = new SlideShowForm(selectedAlbum, true, index);
            slideshow.Show();
        }  
 
        /// <summary>
        /// This function sorts descends the photos in an Album.
        /// The GUI will sort the thumbnails and descend them in view.
        /// Written By: Adam Reaves
        /// </summary>
        private void SortCurrentAlbumToDescending()
        {
            // If All Photos Album is selected
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                return; //we don't sort main album

            // Select proper album
            mainInterface.sortAlbumPhotosByName(mainInterface.CurrentlySelectedAlbum, PhotoSortOrder.Descending);

            // Display proper album
            SelectAlbum(mainInterface.CurrentlySelectedAlbum,true);
        }

        /// <summary>
        /// This function sorts ascends the photos in an Album.
        /// The GUI will sort the thumbnails and ascend them in view.
        /// Written By: Adam Reaves
        /// </summary>
        private void SortCurrentAlbumToAscending()
        {
            // If All Photos Album is selected
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
                return; //we don't sort main album

            // Select proper album
            mainInterface.sortAlbumPhotosByName(mainInterface.CurrentlySelectedAlbum, PhotoSortOrder.Ascending);

            // Display proper album
            SelectAlbum(mainInterface.CurrentlySelectedAlbum, true);
        }

        /// <summary>
        /// This function wraps the album's description and sets it.
        /// The GUI will display the album's description.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="albumDescrip"></param>
        public void SetAlbumDescrip(string albumDescrip)
        {
            List<string> tempDescrip = new List<string>();

            tempDescrip = Wrap(albumDescrip, 50);

            if (tempDescrip.Count == 1)
            {
                albumDescripTopLabel.Text = tempDescrip[0];
                albumDescripMidLabel.Text = "";
                albumDescripBotLabel.Text = "";
            }
            else if (tempDescrip.Count == 2)
            {
                albumDescripTopLabel.Text = tempDescrip[0];
                albumDescripMidLabel.Text = tempDescrip[1];
                albumDescripBotLabel.Text = "";
            }
            else if (tempDescrip.Count == 3)
            {
                albumDescripTopLabel.Text = tempDescrip[0];
                albumDescripMidLabel.Text = tempDescrip[1];
                albumDescripBotLabel.Text = tempDescrip[2];
            }
            else
            {
                albumDescripTopLabel.Text = "";
                albumDescripMidLabel.Text = "";
                albumDescripBotLabel.Text = "";
            }
        }

        /// <summary>
        /// This function wraps the photo's description and sets it.
        /// The GUI will display the photo's description.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="photoDescrip"></param>
        public void SetPhotoDescrip(string photoDescrip)
        {
            List<string> tempDescrip = new List<string>();

            tempDescrip = Wrap(photoDescrip, 50);

            if (tempDescrip.Count == 1)
            {
                photoDescripTopLabel.Text = tempDescrip[0];
                photoDescripMidLabel.Text = "";
                photoDescripBotLabel.Text = "";
            }
            else if (tempDescrip.Count == 2)
            {
                photoDescripTopLabel.Text = tempDescrip[0];
                photoDescripMidLabel.Text = tempDescrip[1];
                photoDescripBotLabel.Text = "";
            }
            else if (tempDescrip.Count == 3)
            {
                photoDescripTopLabel.Text = tempDescrip[0];
                photoDescripMidLabel.Text = tempDescrip[1];
                photoDescripBotLabel.Text = tempDescrip[2];
            }
            else
            {
                photoDescripTopLabel.Text = "";
                photoDescripMidLabel.Text = "";
                photoDescripBotLabel.Text = "";
            }
        }

        /// <summary>
        /// This function clears the Photo Description Box text.
        /// The GUI will display a blank Photo Description.
        /// Written By: Steven Gonzalez
        /// </summary>
        public void ClearPhotoText()
        {
            photoDescripTopLabel.Text = "";
            photoDescripMidLabel.Text = "";
            photoDescripBotLabel.Text = "";
            photoNameLabel.Text = "";
        }

        /// <summary>
        /// This function sets the first button cell in the album list.
        /// The GUI will display a blank cell next to "All Photos" album.
        /// Written By: Steven Gonzalez
        /// </summary>
        public void SetAlbumList()
        {
            //add an all albums entry
            AddAlbumByName("All Photos", "All Photos", false);

            //delete All Albums button
            var cell = AlbumList[1, 0] = new DataGridViewTextBoxCell();
            cell.Value = ""; // ignored if this column is databound
            cell.ReadOnly = true;
            cell.Style.BackColor = Color.FromKnownColor(KnownColor.Control);
        }

        ///<summary>
        ///Word Wrap in a Console App (C#)
        ///Algorithm Found off BlueOnionSoftware.com
        ///Blog Author is unknown, but a genius.
        ///</summary>
        public static List<string> Wrap(string text, int margin)
        {
            int start = 0, end;
            var lines = new List<string>();
            text = Regex.Replace(text, @"\s", " ").Trim();

            while ((end = start + margin) < text.Length)
            {
                while (text[end] != ' ' && end > start)
                    end -= 1;

                if (end == start)
                    end = start + margin;

                lines.Add(text.Substring(start, end - start));
                start = end + 1;
            }

            if (start < text.Length)
                lines.Add(text.Substring(start));

            return lines;
        }

        /// <summary>
        /// This function sets the available options on the Main Tool Strip.
        /// The GUI will disable the available options based on selection events.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="albumID"></param>
        private void DisableToolStripMenuSpecials(int albumID)
        {
            if (albumID == UNIQUE_ALBUM)
            {
                addPhotoToolStripMenuItem.Enabled = false;
                editAlbumToolStripMenuItem.Enabled = false;
                deleteAlbumToolStripMenuItem.Enabled = false;
                sortPhotoToolStripMenuItem.Enabled = false;
            }
            else
            {
                addPhotoToolStripMenuItem.Enabled = true;
                editAlbumToolStripMenuItem.Enabled = true;
                deleteAlbumToolStripMenuItem.Enabled = true;
                sortPhotoToolStripMenuItem.Enabled = true;
            }

            editPhotoToolStripMenuItem.Enabled = false;
            deletePhotoToolStripMenuItem.Enabled = false;
            viewPhotoToolStripMenuItem.Enabled = false;
        }

        /// <summary>
        /// This function sets the available options on the Main Tool Strip.
        /// The GUI will enable the available options based on selection events.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="albumID"></param>
        private void EnableToolStripMenuSpecials(int albumID)
        {
            if (albumID == UNIQUE_ALBUM)
            {
                addPhotoToolStripMenuItem.Enabled = false;
                editPhotoToolStripMenuItem.Enabled = false;
                deletePhotoToolStripMenuItem.Enabled = false;
                sortPhotoToolStripMenuItem.Enabled = false;
            }
            else
            {
                addPhotoToolStripMenuItem.Enabled = true;
                editPhotoToolStripMenuItem.Enabled = true;
                deletePhotoToolStripMenuItem.Enabled = true;
                sortPhotoToolStripMenuItem.Enabled = true;
            }
            viewPhotoToolStripMenuItem.Enabled = true;
        }

        /// <summary>
        /// This function sets the available options on the Album Context Menu.
        /// The GUI will display the available options based on selection events.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void AlbumContextMenu_Opening(object sender, CancelEventArgs e)
        {
            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
            {
                deleteAlbumContextMenuItem.Enabled = false;
                editAlbumContextMenuItem.Enabled = false;
            }
            else
            {
                deleteAlbumContextMenuItem.Enabled = true;
                editAlbumContextMenuItem.Enabled = true;
            }
        }

        /// <summary>
        /// This function sets the available options on the Photo Context Menu.
        /// The GUI will display the available options based on selection events.
        /// Written By: Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void PhotoContextMenu_Opening(object sender, CancelEventArgs e)
        {
            addPhotoContextMenuItem.Enabled = true;
            sortPhotoContextMenuItem.Enabled = true;

            if (ThumbnailView.SelectedItems.Count == 0)
            {
                deletePhotoContextMenuItem.Enabled = false;
                editPhotoContextMenuItem.Enabled = false;
                viewPhotoContextMenuItem.Enabled = false;
            }
            else
            {
                deletePhotoContextMenuItem.Enabled = true;
                editPhotoContextMenuItem.Enabled = true;
                viewPhotoContextMenuItem.Enabled = true;
            }            

            if (mainInterface.CurrentlySelectedAlbum == UNIQUE_ALBUM)
            {
                addPhotoContextMenuItem.Enabled = false;
                deletePhotoContextMenuItem.Enabled = false;
                editPhotoContextMenuItem.Enabled = false;
                sortPhotoContextMenuItem.Enabled = false;
            }
        }

        /// <summary>
        /// This key event fires when the delete key is pressed.
        /// The GUI will delete the proper album.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void AlbumList_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Delete:
                    this.DeleteAlbum();
                    break;
            }
        }

        /// <summary>
        /// This key event fires when the delete key is pressed.
        /// The GUI will delete the proper photo.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ThumbnailView_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Delete:
                    this.DeletePhoto();
                    break;
                case Keys.A:
                    if (e.Control) //select all
                    {
                        foreach (ListViewItem item in ThumbnailView.Items)
                            item.Selected = true;
                    }
                    break;
            }
        }

        ///<summary>
        ///Close the program by selecting the "Close" button from the top menu
        ///created by Michael Flood, Nov 7, 2011
        ///</summary>
        private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        ///<summary>
        ///This is the main function for displaying the "About Us" box
        ///created by Michael Flood, Nov 7, 2011
        ///</summary>
        private void userManualToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            { //Create a link to the user manual and start the process
                System.Diagnostics.Process.Start(@"UserManual(Cycle3).pdf");
            }
            catch
            {

            }

        }

        ///<summary>
        ///This is the function that allows the user to view the "Users Guide" 
        ///This requires that the user have Adobe Reader installed
        ///created by Joseph Alfred, Nov 7, 2011
        ///</summary>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BAAboutBox aboutBox = new BAAboutBox();
            aboutBox.ShowDialog();
        }

        /// <summary>
        /// This key event fires when the Add Album Menu Item is selected.
        /// The GUI will launch the Add Album Wizard.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addAlbumToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.AddAlbumByWizard();
        }

        /// <summary>
        /// This key event fires when the Delete Album Menu Item is selected.
        /// The GUI will delete the selecte album.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteAlbumToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.DeleteAlbum();
        }

        /// <summary>
        /// This key event fires when the Edit Album Menu Item is selected.
        /// The GUI will launch the Edit Album Wizard.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editAlbumToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.EditAlbum();
        }        

        /// <summary>
        /// This key event fires when the Add Photo Menu Item is selected.
        /// The GUI will launch a dialog to select photos to add.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addPhotoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.AddPhotoByPrompt(mainInterface.CurrentlySelectedAlbum);
        }

        /// <summary>
        /// This key event fires when the Delete Photo Menu Item is selected.
        /// The GUI will launch sort the photos in ascending order.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deletePhotoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.DeletePhoto();
        }

        /// <summary>
        /// This key event fires when the Edit Photo Menu Item is selected.
        /// The GUI will launch a dialog to edit photo selected.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editPhotoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditPhoto();
        }

        /// <summary>
        /// This key event fires when the View Photo Menu Item is selected.
        /// The GUI will launch a dialog to view photo selected.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewPhotoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ViewPhoto();
        }

        /// <summary>
        /// This key event fires when the View SlideShow Menu Item is selected.
        /// The GUI will launch the Slide Show Form.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewSlideshowAlbumToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartSlideShow();
        }

        /// <summary>
        /// This key event fires when the Sort Descending Menu Item is selected.
        /// The GUI will launch sort the photos in descending order.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortPhotosDescendingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.SortCurrentAlbumToDescending();
        }

        /// <summary>
        /// This key event fires when the Sort Ascending Menu Item is selected.
        /// The GUI will launch sort the photos in ascending order.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortPhotosAscendingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.SortCurrentAlbumToAscending();
        }

        /// <summary>
        /// This key event fires when a thumbnail is selected or clicked on.
        /// The GUI will select photo thumbnail for various tasks.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        private void ThumbnailView_Click(object sender, EventArgs e)
        {
            SelectPhoto();
        }

        /// <summary>
        /// This key event fires when a thumbnail is double-clicked.
        /// The GUI will launch a dialog to view photo selected.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThumbnailView_DoubleClick(object sender, EventArgs e)
        {
            ViewPhoto();
        } 
        
        /// <summary>
        /// This key event fires when the Add Album Context Item is selected.
        /// The GUI will launch the Add Album Wizard.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addAlbumContextMenuItem_Click(object sender, EventArgs e)
        {
            this.AddAlbumByWizard();
        }

        /// <summary>
        /// This key event fires when the Delete Album Context Item is selected.
        /// The GUI will delete the selecte album.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteAlbumContextMenuItem_Click(object sender, EventArgs e)
        {
            this.DeleteAlbum();
        }

        /// <summary>
        /// This key event fires when the Edit Album Context Item is selected.
        /// The GUI will launch the Edit Album Wizard.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editAlbumContextMenuItem_Click(object sender, EventArgs e)
        {
            this.EditAlbum();
        }

        /// <summary>
        /// This key event fires when the View SlideShow Context Item is selected.
        /// The GUI will launch the Slide Show Form from beginning of Album.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewSlideshowAlbumContextMenuItem_Click(object sender, EventArgs e)
        {
            StartSlideShow();
        }

        /// <summary>
        /// This key event fires when the Add Photo Context Item is selected.
        /// The GUI will launch a dialog to select photos to add.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            this.AddPhotoByPrompt(mainInterface.CurrentlySelectedAlbum);
        }

        /// <summary>
        /// This key event fires when the Delete Photo Context Item is selected.
        /// The GUI will launch sort the photos in ascending order.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deletePhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            this.DeletePhoto();
        }        

        /// <summary>
        /// This key event fires when the Edit Photo Context Item is selected.
        /// The GUI will launch a dialog to edit photo selected.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            EditPhoto();
        }

        /// <summary>
        /// This key event fires when the View Photo Context Item is selected.
        /// The GUI will launch a dialog to view photo selected.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            ViewPhoto();
        }
        
        /// <summary>
        /// This key event fires when the View SlideShow Context Item is selected.
        /// The GUI will launch the Slide Show Form.
        /// Written By: Steven Gonzalez & Adam Reaves
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewSlideShowPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            int index;

            if (ThumbnailView.SelectedItems.Count == 0)
                index = 0;
            else
                index = ThumbnailView.SelectedItems[0].Index;

            this.StartSlideShowAtPicture(index);
        }


        /// <summary>
        /// This key event fires when the Sort Descending Context Item is selected.
        /// The GUI will launch sort the photos in descending order.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortToDescendingPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            this.SortCurrentAlbumToDescending();
        }

        /// <summary>
        /// This key event fires when the Sort Ascending Context Item is selected.
        /// The GUI will launch sort the photos in ascending order.
        /// Written By: Adam Reaves & Steven Gonzalez
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortToAscendingPhotoContextMenuItem_Click(object sender, EventArgs e)
        {
            this.SortCurrentAlbumToAscending();
        }

    }
}
